<template>
  <div class="cart-box">
    <!--公用头部-->
    <custom-header :title="'购物车'" :noback="true"></custom-header>
    <!--所选商品主体-->
    <div class="cart-body">
      <!--多选框群组，groupChange 方法监听van-checkbox的变化 result为所选的购物车上单项id数组-->
      <van-checkbox-group @change="groupChange" v-model="result" ref="checkboxGroup">
        <!--vant 提供的cell组件，list为接口请求回来的购物车商品列表，此处通过v-for循环输出-->
        <van-swipe-cell :right-width="50" v-for="(item, index) in list" :key="index">
          <div class="good-item">
            <!--checkbox组件的name属性设定的值，是groupChange方法返回参数的数组单项-->
            <van-checkbox :name="item.cartItemId" />
            <!--图片通过全局过滤项过滤-->
            <div class="good-img">
              <img :src="$filters.prefix(item.goodsCoverImg)" alt="">
            </div>
            <div class="good-desc">
              <div class="good-title">
                <!--商品名称-->
                <span>{{ item.goodsName }}</span>
                <!--商品数量-->
                <span>{{ item.goodsCount }}</span>
              </div>
              <div class="good-btn">
                <!--商品单价-->
                <div class="price">￥{{ item.sellingPrice }}</div>
                <!--计步器用于控制购买商品的数量，每改变一次，调用一次modifyCart修改购物车，通过设置async-change支持异步修改-->
                <van-stepper integer :min="1" :max="5" :model-value="item.goodsCount" :name="item.cartItemId"
                  async-change @change="onChange" />
              </div>
            </div>
          </div>
          <!--设置滑动删除，当向左滑动时，右侧会出现删除按钮-->
          <template #right>
            <van-button square icon="delete" type="danger" class="delete-button" @click="deleteGood(item.cartItemId)" />
          </template>
        </van-swipe-cell>
      </van-checkbox-group>
    </div>
    <!--提交组件，专门用于电商购物车提交-->
    <van-submit-bar v-if="list.length > 0" class="submit-all van-hairline--top" :price="total * 100" button-text="结算"
      @submit="onSubmit">
      <van-checkbox @click="allCheck" v-model:checked="checkAll">全选</van-checkbox>
    </van-submit-bar>
    <!--当没有购物车商品时，空状态-->
    <div class="empty" v-if="!list.length">
      <img class="empty-cart" src="https://s.yezgea02.com/1604028375097/empty-car.png" alt="空购物车">
      <div class="title">购物车空空如也</div>
      <van-button round color="#1baeae" type="primary" @click="goTo" block>前往选购</van-button>
    </div>

    <nav-bar></nav-bar>
  </div>
</template>
<script>
import { reactive, onMounted, computed, toRefs } from 'vue'
import { useRouter } from 'vue-router'
import { useStore } from 'vuex'
import { Toast } from 'vant'
import NavBar from 'components/NavBar.vue' //公用底部导航栏
import CustomHeader from 'components/CustomHeader.vue' //公用头部组件
import { getCart, deleteCartItem, modifyCart } from 'service/cart' //引入购物车相关接口方法

export default {
  //注册组件
  components: {
    NavBar,
    CustomHeader
  },
  setup() {
    const router = useRouter() //生成路由实例
    const store = useStore() //生成全局状态管理实例
    const state = reactive({
      list: [], //购物车商品列表
      result: [], //商品多选数组
      checkAll: true //是否全选
    })

    onMounted(() => {
      //初始化方法
      initData()
    })
    const initData = async () => {
      //进入购物车页面，加载数据动画
      Toast.loading({ message: '加载中...', forbidClick: true });
      const { data } = await getCart({ pageNumber: 1 })
      /**
       * 购物车列表返回的数据结构
       * data: [
       * {
       *  cartItemId: 购物车列表单项id
       *  goodsCount: 单项商品数量
       *  goodsCoverImg:商品图片
       *  goodsId: 商品id
       *  goodsName: 商品名称
       *  sellingPrice: 商品单价
       * 
       * }
       * ]
       */
      state.list = data //赋值给list
      //默认全部选中，将data中的cartItemId通过map方法制作成数组，如[1,2,3,4]
      state.result = data.map(item => item.cartItemId)
      Toast.clear() //取消动画
    }
    const total = computed(() => {
      let sum = 0
      //total变量，通过computed方法监听result的变化，随之将list过滤出来
      let _list = state.list.filter(item => state.result.includes(item.cartItemId))
      //通过forEach方法累加商品总价
      _list.forEach(item => {
        sum += item.goodsCount * item.sellingPrice
      })
      return sum
    })
    //返回
    const goBack = () => {
      router.go(-1)
    }
    //前往首页
    const goTo = () => {
      router.push({ path: '/home' })
    }
    //当计步器改变时，触发
    const onChange = async (value, detail) => {
      if (value > 5) {
        Toast.fail('超出单个商品的最大购买数量')
        return
      }
      if (value < 1) {
        Toast.fail('商品数量不得小于0')
        return
      }
      //如果改变后的商品数量和改变之前的商品数量相同，则不再往下执行
      if (state.list.filter(item => item.cartItemId == detail.name)[0].goodsCount == value) {
        return Toast.loading({ message: '修改中...', forbidClick: true });

      }
      const params = {
        cartItemId: detail.name,
        goodsCount: value
      }
      //根据购物车单项id，改变商品数量
      await modifyCart(params)
      //改变成功后，将对应的数量进行手动增加
      state.list.forEach(item => {
        if (item.cartItemId == detail.name) {
          item.goodsCount = value
        }
      })
      Toast.clear();
    }

    //提交购物车方法
    const onSubmit = async () => {
      if (state.result.length == 0) {
        Toast.fail('请选择商品进行结算')
        return
      }
      const params = JSON.stringify(state.result)
      //提交购物车，将所选的购物车商品id通过浏览器查询参数传递给CreateOrder.vue,生成订单页面
      router.push({ path: '/create-order', query: { cartItemIds: params } })
    }
    //删除商品的方法
    const deleteGood = async (id) => {
      await deleteCartItem(id)
      //删除商品后，需要更新全局购物车商品数量
      store.dispatch('updateCart')
      initData()
    }
    //多选框监听change事件
    const groupChange = (result) => {
      //当result的长度等于商品列表的长度时，全选状态为true
      if (result.length == state.list.length) {
        state.checkAll = true
      } else {
        //否则为false
        state.checkAll = false
      }
      //赋值result
      state.result = result
    }
    //全选状态变化方法
    const allCheck = () => {
      if (!state.checkAll) {
        state.result = state.list.map(item => item.cartItemId)
        console.log(state.checkAll)
      } else {
        state.result = []
      }
    }
    return {
      ...toRefs(state),
      total,
      goBack,
      goTo,
      onChange,
      onSubmit,
      deleteGood,
      groupChange,
      allCheck
    }

  }

}
</script>
<style lang="less">
@import '../theme/custom';

.cart-box {
  .cart-header {
    .fj();
    .wh(100%, 44px);
    line-height: 44px;
    padding: 0 10px;
    .boxSizing();
    color: #252525;
    background: #fff;
    border-bottom: 1px solid #dcdcdc;

    .cart-name {
      font-size: 14px;
    }
  }

  .cart-body {
    margin: 16px 0 100px 0;
    padding-left: 10px;
    padding-bottom: 100px;

    .good-item {
      display: flex;

      .good-img {
        img {
          .wh(100px, 100px)
        }
      }

      .good-desc {
        display: flex;
        flex-direction: column;
        justify-content: space-between;
        flex: 1;
        padding: 20px;

        .good-title {
          display: flex;
          justify-content: space-between;
        }

        .good-btn {
          display: flex;
          justify-content: space-between;

          .price {
            font-size: 16px;
            color: red;
            line-height: 28px;
          }

          .van-icon-delete {
            font-size: 20px;
            margin-top: 4px;
          }
        }
      }
    }

    .delete-button {
      width: 50px;
      height: 100%;
    }
  }

  .empty {
    width: 50%;
    margin: 0 auto;
    text-align: center;

    .empty-cart {
      width: 150px;
      margin-bottom: 20px;
    }

    .van-icon-smile-o {
      font-size: 50px;
    }

    .title {
      font-size: 16px;
      margin-bottom: 20px;
    }
  }

  .submit-all {
    margin-bottom: 50px;

    .van-checkbox {
      margin-left: 10px;
    }

    .van-submit-bar__text {
      margin-right: 10px;
    }

    .van-submit-bar__button {
      background: @primary;
    }
  }

  .van-checkbox__icon--checked .van-icon {
    background-color: @primary;
    border-color: @primary;
  }
}
</style>